package liquidfs.ui.ftp;

import java.io.*;
import java.util.*;
import java.util.logging.*;

import liquidfs.data.*;
import liquidfs.data.fs.*;

import org.apache.ftpserver.ftplet.*;

public class LiquidFtpFile implements FtpFile {

   private LiquidObject object;
   private static Logger log = Logger.getLogger("liquidfs.ui.ftp");
   
   public LiquidFtpFile (LiquidObject object) {
      this.object = object;
      log.setLevel(Level.FINE);
   }
   
   @Override
   public InputStream createInputStream(long offset) throws IOException {
      log.fine("LiquidFtpFile(" + object.getPath() + ").createInputStream(" + offset + ")");
      
      // Open the file
      LiquidFile file = object.asFile();
      file.open(OpenMode.READ);
      
      // Return the stream
      return file.getInputStream(offset);
   }

   @Override
   public OutputStream createOutputStream(long offset) throws IOException {
      log.fine("LiquidFtpFile(" + object.getPath() + ").createOutputStream(" + offset + ")");
      
      LiquidFile file = object.asFile();
      
      // Open the file
      file.open(OpenMode.READ_WRITE);
      
      // Truncate the file at the point that we're writing at
      // (FTP has no way of explicitly setting file length, so if we cut it off here, it will grow as we write it and end at the right place)
      file.setLength(offset);
      
      // Return the stream
      return file.getOutputStream(offset);
   }

   @Override
   public boolean delete() {
      log.fine("LiquidFtpFile(" + object.getPath() + ").delete()");
      return false;
   }

   @Override
   public boolean doesExist() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").doesExist()");
      return object.exists();
   }

   @Override
   public String getAbsolutePath() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").getAbsolutePath()");
      return object.getPath();
   }

   @Override
   public String getGroupName() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").getGroupName()");
      return null;
   }

   @Override
   public long getLastModified() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").getLastModified()");
      return object.getModificationDate().getTime();
   }

   @Override
   public int getLinkCount() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").getLinkCount()");
      return 0;
   }

   @Override
   public String getName() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").getName()");
      return object.getName();
   }

   @Override
   public String getOwnerName() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").getOwnerName()");
      return null;
   }

   @Override
   public long getSize() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").getSize()");
      return object.getSize();
   }

   @Override
   public boolean isDirectory() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").isDirectory()");
      return object.isDirectory();
   }

   @Override
   public boolean isFile() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").isFile()");
      return !object.isDirectory();
   }

   @Override
   public boolean isHidden() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").isHidden()");
      return false;
   }

   @Override
   public boolean isReadable() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").isReadable()");
      return true;
   }

   @Override
   public boolean isRemovable() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").isRemovable()");
      return false;
   }

   @Override
   public boolean isWritable() {
      log.finer("LiquidFtpFile(" + object.getPath() + ").isWritable()");
      return true;
   }

   @Override
   public List<FtpFile> listFiles() {
      log.fine("LiquidFtpFile(" + object.getPath() + ").listFiles()");
      
      LiquidDirectory dir = object.asDirectory();
      List<LiquidObject> contents = dir.getContents();
      
      List<FtpFile> list = new ArrayList<FtpFile>(contents.size());
      for (LiquidObject child : contents) {
         list.add(new LiquidFtpFile(child));
      }
      
      return list;
   }

   @Override
   public boolean mkdir() {
      log.fine("LiquidFtpFile(" + object.getPath() + ").mkdir()");
      return false;
   }

   @Override
   public boolean move(FtpFile file) {
      log.fine("LiquidFtpFile(" + object.getPath() + ").move(" + file.getAbsolutePath() + ")");
      return false;
   }

   @Override
   public boolean setLastModified(long timestamp) {
      log.fine("LiquidFtpFile(" + object.getPath() + ").setLastModified(" + new Date(timestamp) + ")");
      return false;
   }

}
